<template>
  <div class="webglDiv"></div>
</template>

<script>
import * as THREE from 'three';
export default {
  name: "WebglPoints3",
  methods: {
    init() {
      let vertexshader = `
        attribute float scale;
        void main() {
              vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
              gl_PointSize = scale * ( 300.0 / - mvPosition.z );
              gl_Position = projectionMatrix * mvPosition;
        }
      `;
      let fragmentshader =`
         uniform vec3 color;
         void main() {
             if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.475 ) discard;
             gl_FragColor = vec4( color, 1.0 );
         }
      `;
      let webglDiv = document.getElementsByClassName('webglDiv')[0];
      let camare = new THREE.PerspectiveCamera(45, webglDiv.clientWidth/webglDiv.clientHeight, 1, 1000);
      camare.position.z = 1000;

      let scene = new THREE.Scene();

      const SEPARATION = 100, AMOUNTX = 50, AMOUNTY = 50;
      // 初始化粒子的位置
      const positions = new Float32Array(AMOUNTX*AMOUNTY*3);
      const scales = new Float32Array(AMOUNTX*AMOUNTY);
      let positioni = 0;
      let positionj = 0;
      for (let i = 0; i < AMOUNTX; i++) {
        for (let j = 0; j < AMOUNTY; j++) {
          positions[ positioni ] = i * SEPARATION - ( ( AMOUNTX * SEPARATION ) / 2 ); // x
          positions[ positioni + 1 ] = 0; // y
          positions[ positioni + 2 ] = j * SEPARATION - ( ( AMOUNTY * SEPARATION ) / 2 ); // z
          scales[ positionj ] = 1;
          positioni = positioni +3;
          positionj = positionj + 1;
        }
      }
      const geometry = new THREE.BufferGeometry();
      geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
      geometry.setAttribute('scale', new THREE.BufferAttribute(scales, 1));
      const meterial = new THREE.ShaderMaterial({
        uniforms: {
          color: {value: new THREE.Color( 0x00BFFF )}
        },
        vertexShader: vertexshader,
        fragmentShader: fragmentshader
      });
      let particles = new THREE.Points(geometry, meterial);
      scene.add(particles);

      let renderer = new THREE.WebGLRenderer({antialias: true});
      renderer.setPixelRatio( window.devicePixelRatio );
      renderer.setSize( webglDiv.clientWidth, webglDiv.clientHeight );
      webglDiv.appendChild(renderer.domElement);

      let mouseX = 0, mouseY = 0;

      let windowHalfX = window.innerWidth / 2;
      let windowHalfY = window.innerHeight / 2;

      function onPointerMove( event ) {

        if ( event.isPrimary === false ) return;

        mouseX = event.clientX - windowHalfX;
        mouseY = event.clientY - windowHalfY;

      }
      webglDiv.addEventListener( 'pointermove', onPointerMove );

      let  count = 0;
      let animate = function () {
         requestAnimationFrame( animate );
        camare.position.x += ( mouseX - camare.position.x ) * .05;
        camare.position.y += ( - mouseY - camare.position.y ) * .05;
        camare.lookAt( scene.position );
        const positions = particles.geometry.attributes.position.array;
        const scales = particles.geometry.attributes.scale.array;
        let i = 0, j = 0;
        for ( let ix = 0; ix < AMOUNTX; ix ++ ) {
          for ( let iy = 0; iy < AMOUNTY; iy ++ ) {
            positions[ i + 1 ] = ( Math.sin( ( ix + count ) * 0.3 ) * 50 ) +
                ( Math.sin( ( iy + count ) * 0.5 ) * 50 );
            scales[ j ] = ( Math.sin( ( ix + count ) * 0.3 ) + 1 ) * 20 +
                ( Math.sin( ( iy + count ) * 0.5 ) + 1 ) * 20;
            i += 3;
            j ++;
          }
        }
        particles.geometry.attributes.position.needsUpdate = true;
        particles.geometry.attributes.scale.needsUpdate = true;
        renderer.render( scene, camare );
        count += 0.1;
      }
      animate();
    }
  },
  mounted() {
    this.init();
  }
}
</script>

<style lang="less" scoped>
.webglDiv {
  height: 100%;
}
</style>